﻿#include "hexbin.h"
#include <QRegularExpression>
#include <QTextStream>


QByteArray HexBin::parseHexString(const QString &str, bool* ok)
{
    QString hexStr = str;
    // 1. 移除所有空白字符（空格、制表符等）
    hexStr.remove(QRegularExpression("\\s+"));

    // 2. 检查是否为有效的16进制字符串（可选）
    if (hexStr.length() % 2 != 0) {
        if (ok) *ok = false;
        return QByteArray();
    }

    // 3. 转换为 QByteArray
    QByteArray ret = QByteArray::fromHex(hexStr.toLatin1());
    if (ret.length() * 2 != hexStr.length()) {
        if (ok) *ok = false;
        return QByteArray();
    }
    if (ok) *ok = true;
    return ret;
}

QString HexBin::hexFormat(const QByteArray &data)
{
    const int bytesPerLine = 16;
    const int chunkSize = 8; // 每8字节分块

    QString result;
    QTextStream stream(&result);

    for (int i = 0; i < data.size(); i += bytesPerLine) {
        // 格式化地址部分 (8位十六进制，前导0)
        stream << QString("%1").arg(i, 8, 16, QLatin1Char('0')).toUpper() << "  ";

        // 格式化十六进制数据部分
        QByteArray lineData = data.mid(i, bytesPerLine);
        QString hexPart;
        QString asciiPart;

        for (int j = 0; j < bytesPerLine; j++) {
            if (j < lineData.size()) {
                // 添加十六进制字节
                uchar byte = static_cast<uchar>(lineData[j]);
                hexPart += QString("%1 ").arg(byte, 2, 16, QLatin1Char('0')).toUpper();

                // 添加ASCII字符或点
                if (byte >= 0x20 && byte <= 0x7E) { // 可打印ASCII范围
                    asciiPart += QChar(byte);
                } else {
                    asciiPart += '.';
                }
            } else {
                hexPart += "   "; // 填充空格
                asciiPart += ' ';
            }

            // 在8字节后添加额外空格
            if (j == chunkSize - 1) {
                hexPart += " ";
            }
        }

        stream << hexPart << " |" << asciiPart << "|";

        // 如果不是最后一行，添加换行
        if (i + bytesPerLine < data.size()) {
            stream << "\n";
        }
    }

    return result;
}

QString HexBin::normalizeHexString(const QString &input, bool *ok)
{
    if (input.trimmed().isEmpty()){
        if (ok) *ok = true;
        return QString();
    }

    QString text = input;

    // 1. 统一去掉常见的十六进制前缀形式
    text.replace(QRegularExpression("(0x|0X|\\\\x|\\\\X)"), "");

    // 2. 去掉分隔符（空格、换行、逗号、分号、括号、中括号等）
    text.remove(QRegularExpression("[\\s,;:\\(\\)\\[\\]\\{\\}]"));

    // 3. 检查是否包含非法字符（非 0-9 a-f A-F）
    QRegularExpression invalid("[^0-9a-fA-F]");
    auto match = invalid.match(text);
    if (match.hasMatch()) {
        if (ok) *ok = false;
        return QString();
    }

    // 4. 如果长度为奇数，补一个 0 在最前面
    if (text.length() % 2 != 0)
        text.prepend('0');

    // 5. 分组每两个字符为一组
    QStringList bytes;
    for (int i = 0; i < text.length(); i += 2)
        bytes << text.mid(i, 2).toUpper();

    if (ok) *ok = true;

    // 6. 用空格连接
    return bytes.join(' ');
}
